package sk.mka.phd.googleagent.ngram;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.logging.Level;
import org.apache.log4j.Logger;
import sk.mka.phd.files.reader.load.ILoadData;
import sk.mka.phd.files.reader.load.arbitrary.ArbitraryDataLoadFileImpl;
import sk.mka.utils.tools.filesystem.FileUtils;

/**
 * @author bracek
 * @date Jul 7, 2010
 */
public final class GoogleNgramAgent extends AbstractNgramAgent implements IGoogleNgram {

    private static final Logger log = Logger.getLogger(GoogleNgramAgent.class);
    private ArrayList incomingArrayList = new ArrayList();
    private ArrayList<String> lettersArray = new ArrayList<String>();
    private int hashMapIndex = 0;

    public GoogleNgramAgent(final String finalPath, final String separator) {
        squareDataLoadFile = new ArbitraryDataLoadFileImpl(finalPath, separator);
    }

    private void compressOutput(final String letterForCompress) throws IOException {

        final String finalPathCompress = dictionaryOutput + letterForCompress;
//        final String finalPathCompress =  letterForCompress;
        String bz2filename = finalPathCompress + ".tar.bz2";
        String commandCompress = "tar cvjf " + bz2filename + " " + finalPathCompress;
        System.out.println("commandCompress = " + commandCompress);
        Runtime.getRuntime().exec(commandCompress);
        final String uncompressedFilePath = dictionaryOutput + letterForCompress;
        final String removeUncompressedFile = "rm -rvf " + uncompressedFilePath;
        Runtime.getRuntime().exec(removeUncompressedFile);
    }

    private void loadInputData() {
        ((ILoadData) squareDataLoadFile).loadData();
        ArrayList<Object> linesHashSet = squareDataLoadFile.getLines();
        for (Object object : linesHashSet) {
            incomingArrayList.add(object);
        }
    }

    @Override
    public void createNgramModel() {
        for (int i = 0; i < ngram; i++) {
            try {
                loadInputData();
                for (Object object : incomingArrayList) {
                    ArrayList<Object> col = (ArrayList<Object>) object;
                    generateAllCombinationForWord(col, incomingArrayList);
                }

                //compress last letter
                int prevIndex = hashMapIndex - 1;
                final String letterForCompress = lettersArray.get(prevIndex);
                compressOutput(letterForCompress);
            } catch (IOException ex) {
                java.util.logging.Logger.getLogger(GoogleNgramAgent.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    protected void writeBufferToFile(final String filePath) {
        try {
            bufferOutput = FileUtils.openFileForWriting(filePath, Boolean.TRUE);
            for (Object object : finalSet) {
                ArrayList<Object> arrayList = (ArrayList<Object>) object;
                for (Object value : arrayList) {
                    bufferOutput.write(value.toString());
                    bufferOutput.write(" ");
                }
                bufferOutput.write("\n");
            }
            bufferOutput.close();
        } catch (IOException ex) {
            log.debug(ex);
        }

    }

    private void generateAllCombinationForWord(ArrayList line, ArrayList tmp) {

        finalSet = new HashSet();
        finalSet.add(line);

        for (Object object1 : tmp) {

            ArrayList<Object> newLine = (ArrayList<Object>) object1;

            boolean write = true;
            if (newLine.size() + line.size() <= ngram) {
                if (line.size() >= newLine.size()) {
                    if (line.containsAll(newLine)) {
                        write = false;
                    }
                } else {

                    if (newLine.containsAll(line)) {
                        write = false;
                    }
                }

                if (write) {
                    if (!newLine.equals(line)) {
                        ArrayList newArray = new ArrayList();
                        for (Object object : line) {
                            newArray.add(object);
                        }

                        for (Object object : newLine) {
                            newArray.add(object);
                        }
                        finalSet.add(newArray);
                    }
                }
            }
        }

        final String element = (String) line.get(0);
        final String firstLetter = element.substring(0, 1);
        final String finalPath = dictionaryOutput + firstLetter;
        writeBufferToFile(finalPath);

        //set first letter to
        if (lettersArray.isEmpty()) {
            lettersArray.add(firstLetter);
            hashMapIndex++;
        } else {
            if (!lettersArray.contains(firstLetter)) { //adding new letter, compress previous
                try {
                    //adding new letter, compress previous
                    int prevIndex = hashMapIndex - 1;
                    final String letterForCompress = lettersArray.get(prevIndex);
                    compressOutput(letterForCompress);

                    //zip
//                    final String finalPathCompress = inputFolder + letterForCompress;
//                    String bz2filename = finalPathCompress + ".zip";
//                    String commandCompress = "zip -r " + bz2filename + " " + finalPathCompress;
//                    System.out.println("commandCompress = " + commandCompress);
//                    Runtime.getRuntime().exec(commandCompress);

                    lettersArray.add(firstLetter);
                    hashMapIndex++;
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(GoogleNgramAgent.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
        }
    }
}
